package test.SoundDriver;

import java.util.ArrayList;
import java.util.Arrays;

import android.hardware.SensorManager;

public class Quantization {
	private static final float BLANK = -999;
	private static final int WINDOW = 3; //default size of buffer
	private static final int SAMPLESIZE = 50;
	private float[] sampleX;
	private float[] sampleY;
	private float[] sampleZ;
	private int position = 0;
	
	public Quantization() {
		sampleX = new float[SAMPLESIZE];
		sampleY = new float[SAMPLESIZE];
		sampleZ = new float[SAMPLESIZE];		
		clear();
	}

	private void clear() {
		Arrays.fill(sampleX, BLANK);
		Arrays.fill(sampleY, BLANK);
		Arrays.fill(sampleZ, BLANK);
	}
	
	public boolean add(float valuesAcc[]) {
		sampleX[position] = valuesAcc[0];
		sampleY[position] = valuesAcc[1];
		sampleZ[position] = valuesAcc[2];
		//System.out.println(values[0]);
		//System.out.println(values[1]);
		//System.out.println(values[2]);
		//System.out.println("---");		
		position++;
		if (position == SAMPLESIZE) {
			position = 0;
			return false; // full, start from the beginning
		}		
		return true; // empty
	}
	
	/**
	 * Smooth the source samples to avoid hand vibration
	 * @param values
	 * @return
	 */
	public void smoothSamples() {
		sampleX = ImageFilterUtil.medValueFilter(sampleX, WINDOW);
		sampleY = ImageFilterUtil.medValueFilter(sampleY, WINDOW);
		sampleZ = ImageFilterUtil.medValueFilter(sampleZ, WINDOW);
	}
	
	public void quantizeSamples() {
		for (int i=0; i<SAMPLESIZE; i++){
			sampleX[i] = quantizeHelper(sampleX[i]);
		}
		for (int i=0; i<SAMPLESIZE; i++){
			sampleY[i] = quantizeHelper(sampleY[i]);
		}
		for (int i=0; i<SAMPLESIZE; i++){
			sampleZ[i] = quantizeHelper(sampleZ[i]);
		}		
	}
	
	private float quantizeHelper(float a){
		if (a == 0) return 0;
		if (a > 2*SensorManager.GRAVITY_EARTH){
			return 16;
		}else if(a > SensorManager.GRAVITY_EARTH && a < 2*SensorManager.GRAVITY_EARTH){
			return 10+(int)(5*(a/SensorManager.GRAVITY_EARTH -1));
		} else if (a > 0 && a < SensorManager.GRAVITY_EARTH){
			return (int)(10*a/SensorManager.GRAVITY_EARTH);
		} else if(a < 0 && a > -SensorManager.GRAVITY_EARTH){
			return (int)(10*a/SensorManager.GRAVITY_EARTH);
		} else if (a < SensorManager.GRAVITY_EARTH && a > -2*SensorManager.GRAVITY_EARTH){
			return 10+(int)(5*(a/SensorManager.GRAVITY_EARTH +1));
		} else return 16;
	}
	
}
